package com.yonyou.pmclouds.basecom.async;

public interface AsyncInvocation {
    /**
     * 调用前准备并恢复数据，如果info中存在数据，可以跳过该过程
     */
    int prepare(InvokingTracer tracer) throws Exception;

    /**
     * 执行调用
     */
    int invoke(InvokingTracer tracer) throws Exception;

    /**
     * 发生异常时，进行处理
     */
    int onException(Exception ex, InvokingTracer tracer);

    /**
     * 释放占用的资源
     */
    void cleanResource(InvokingTracer tracer);

    AsyncInvocationInfo getCurrentInfo();

    interface InvocationState {
        /**
         * 已经提交、但未确认需要执行
         */
        int STATE_PREPARING = -20;
        /**
         * 已经提交、确认需要执行
         */
        int STATE_PREPARED = -10;
        /**
         * 被其他机器调用中
         * <br>这个状态不进入数据库，只是用来与框架交互
         */
        int STATE_INVOKING_ORTHER = -1;
        /**
         * 调用中
         */
        int STATE_INVOKING = 0;
        /**
         * 调用成功
         */
        int STATE_SUCCESS = 10;
        /**
         * 调用失败，要求自动重试（暂未支持）
         */
        int STATE_FAILED_RETRY = 20;
        /**
         * 调用失败，需要业务自动处理
         */
        int STATE_FAILED_AUTO = 30;
        /**
         * 调用失败，需要人工介入（该状态可能触发邮件、短信等方式提醒，暂未实现）
         */
        int STATE_FAILED_MANUAL = 40;
        /**
         * 调用失败，不做处理
         */
        int STATE_FAILED_DO_NOTHING = 50;
    }


    /**
     * 根据调用信息生成调用器的工厂，该接口被调用时应该是无状态的。
     * <br/>考虑到有些情况下服务单纯传入info，可能一些依赖的服务不易获取，或者构建逻辑复杂，故使用工厂创建
     * AsyncInvocationInfo#executionClass+"Factory"构成工厂的类型，优先根据类型在spring中查找，无法获取，则直接尝试调用无参构造方法
     */
    interface AsyncInvocationFactory {
        AsyncInvocation createInvocationFromInfo(AsyncInvocationInfo info);
    }
}
